home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Music / B / BeepShuffle 0.3 Folder / BeepShuffle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-25  |  3.0 KB  |  125 lines  |  [TEXT/KAHL]

  1. /* BeepShuffle.c */
  2. /*    BeepShuffle © 1990, by Alex Chaffee
  3.     chaffee@reed.uucp    CIS:71210,1117
  4.     Reed College Box 259, Portland OR 97202
  5.  
  6.     This source may be freely distributed.
  7.     
  8.     Version    Date        History
  9.     0.1        7/21/89    Version 1
  10.     0.2        1/9/90    Legalized tail-patch
  11.                     Implemented true randomness (using Ticks instead of Random)
  12.     0.3        1/25    HPurge() and if (H)
  13.  
  14. /*    An INIT that will patch SysBeep to select
  15.     a random beep from all installed 'snd 's.
  16.     Custom Headers: ON
  17. */
  18.  
  19. /* low-mem globals */
  20. #define    SYSBEEP    0xA9C8                /* SysBeep Trap# */
  21. #define    SndPlayTrap    0x05            /* SndPlay Trap# */
  22. #define    UnTrap    0x9F                /* Unimplemented Trap # */
  23.  
  24. extern unsigned char SoundActive: 0x027E;    /* Is an async sound already playing? */
  25. extern unsigned char SdVolume: 0x0260;        /* volume */
  26.  
  27. /* program globals/constants */
  28. #define int_HIBITOFF    0x7FFF
  29. static long OldSysBeep;                    /*    Former SysBeep trap address    */
  30. #define    SUCCESS    128                    /*    ICN# codes    */
  31. #define    FAIL        129
  32.  
  33. /* forward declarations */
  34. extern pascal void mySysBeep();
  35. extern main();
  36. pascal void ShowINIT(short iconID, short moveX);
  37.  
  38. main()
  39. {
  40.     register Handle H;
  41.     short    theIcn;
  42.     
  43. /* save all system registers */
  44.     asm {
  45.         movem.l    a1-a5/d0-d7, -(SP)
  46.  
  47. /*    Set Up A4 to point to top of resource to access global variables    */
  48.  
  49.         LEA    main, A4    ; put top address in A4
  50.  
  51. /*    Self-preservation        */
  52.  
  53.         LEA    main, A0    ; put address of resource in parameter
  54.         _RecoverHandle
  55.         move.l    a0, H    ; who am i?
  56.     }
  57.     HLock(H);
  58.     DetachResource(H);
  59.  
  60. /*    Check for compatibility    */
  61.  
  62. /*    check to see if SndPlay is implemented as per TN#156.        */
  63.     if (    NGetTrapAddress(SndPlayTrap, ToolTrap) == 
  64.         NGetTrapAddress(UnTrap, ToolTrap)    )
  65.     {    /* failure */
  66.         theIcn = FAIL;
  67.     }
  68.  
  69. /*    Install my beep            */
  70.     else if (Button())                        /*    Startup click -> Failure    */
  71.         theIcn = FAIL;
  72.     else {
  73.         OldSysBeep = GetTrapAddress(SYSBEEP);
  74.         SetTrapAddress(&mySysBeep, SYSBEEP);
  75.         theIcn = SUCCESS;
  76.     }
  77.     ShowINIT(theIcn, -1);
  78.  
  79.     asm {
  80.         movem.l    (SP)+, a1-a5/d0-d7        ; restore registers
  81.     }
  82. }
  83.  
  84. pascal void mySysBeep(duration)
  85. int duration;
  86. {
  87.     register int total;
  88.     register int i;
  89.     register Handle H;
  90.     
  91.     /* since this is a trap routine, we must preserve the registers */
  92.     asm {
  93.         movem.l    a1-a5/d0-d7, -(SP)    ; a6 is lunk, a7 is SP
  94.     /* set up globals */
  95.         LEA main, A4                ; set up globals
  96.     }
  97.  
  98.     if (!SoundActive && SdVolume)    
  99.     {    /* Find snd */
  100.         total = CountResources('snd ');
  101.         if (total)
  102.         {
  103.             i = ((int)Ticks & int_HIBITOFF) % total + 1;    /* non-neg., 1 -> total */
  104.             H = GetIndResource('snd ', i);
  105.             if (H) {
  106.                 SndPlay(0L, H, FALSE);                /* should I error-check?  Nah…    */
  107.                 HPurge(H);                            /* make sure it's cleaned up    */
  108.                 asm {                        /*    return NOW!    */
  109.                     movem.l    (SP)+, a1-a5/d0-d7        ; restore registers
  110.                     UNLK        A6                    ; remove stack frame
  111.                     movea.l    (SP)+, A0                ; get return addr
  112.                     addq.w    #2, SP                ; pop parameter
  113.                     JMP        (A0)                    ; return
  114.                 }
  115.             }
  116.         }
  117.     }
  118.     asm {                        /* else legally jump to real SysBeep    */
  119.         movea.l    OldSysBeep, A0        ; get jump addr
  120.         movem.l    (SP)+, a1-a5/d0-d7        ; restore registers
  121.         UNLK        A6                    ; remove stack frame
  122.         JMP        (A0)                    ; jump
  123.     }
  124. }
  125.